AOP(Aspect Oriented Programming, 面向切面編程)是Spring重要觀念之一,不過在一開始接觸時,我很常將它與過濾器、攔截器功能搞混,但其實使用的場景不太一樣,了解各自的特性後,有助於機制設定的選擇唷!
AOP中文是「面向切面編程」主要處理方法級別的橫切關注點。是否中文每個字都看得懂,湊在一起卻不太懂?沒關係,我當初也是這樣。一起來看看下面的栗子:
AOP指的是在程式中定義一個切入點(Join Point),而在這個點的前後都能切入不同的邏輯執行,這些邏輯即稱為Asperct。
AOP最大的特點是不會破壞原有的程式邏輯,能夠輕鬆將額外的行為注入。常應用於log日誌、事務管理、安全檢查、資源控制等等。
當客戶端瀏覽器發送一次請求,其流程:前端請求→ 後端接收→ 邏輯處理→ 響應返回請求端。當中對應的程式分別是:請求端→ Controllers→ Services→ DAO (結果再往前返回)。當有多個API都需要在Controllers執行某一事務時,傳統作法是重複撰寫一樣的邏輯,冗長且維護麻煩,此時就能使用AOP將此做為一個切面,放入統一的邏輯處理即可。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
@Aspect // 此為aspect註解,表示此類為切面,包含橫切邏輯
@Component // 註冊為Spring的Bean,代表被注入
public class LogAspect {
// 定義切入點的註解,代表切面邏輯會用於此,
// 可具體指定要切入的java,甚至是到方法
@Pointcut("execution(* com.example.api.LogApi.log(..))")
public void log() {
}
@Before("log()") // 定義切入點之前的註解,指定放入的方法
public void doBefore() {
logger.info("---------------- doBefore -----------------");
}
@After("log()") // 定義切入點之後的註解,指定放入的方法
public void doAfter() {
logger.infor("----------------- doAfter -----------------");
}
}
@RestController
public class LogApi {
@GetMapping("/log")
public String log() {
// doSomethings
logger.info("done!!!!");
return "aspect test";
}
}
執行結果會是:
---------------- doBefore -----------------
done!!!!
----------------- doAfter -----------------
有沒有發現AOP、Filter過濾器、Interceptor攔截器可使用的場景都滿類似的,但其實它們的作用範圍跟設計是不同的唷!
AOP是屬於Spring Framework的核心功能之一,使用Spring Boot一樣能簡化其配置,透spring-boot-starter-aop依賴,能更方便且快速的使用其橫切邏輯。
AOP與過濾器、攔截器相比,更能細粒插入邏輯且不干擾原有程式。